package com.mk.util.kuaidi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mk.util.HttpUtils;
import org.osgl.util.S;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;

/**
 * 快递物流查询工具类
 * Created by cb on 2016/12/14.
 */

public class KuaiDiUtils {
//    private static Properties props;
    private static final String kd_key="20e0533b3add5c1d";
    private static final String kd_url="http://api.kuaidi100.com/api";
    private static final String js_key="f1e03d17c7a562be";
    private static final String js_url="http://api.jisuapi.com/express/query";
    private static final String js_company="shentong,shunfeng,tiantian";
    private static final String kdn_key="1a25f237-c0df-4a63-b44e-8e45f3c95be8";
    private static final String kdn_url="http://api.kdniao.cc/Ebusiness/EbusinessOrderHandle.aspx";
    private static final String kdn_id="1278911";


    private static Map<String, String> mapCompany;
    private static char[] base64EncodeChars = new char[]{
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
        'w', 'x', 'y', 'z', '0', '1', '2', '3',
        '4', '5', '6', '7', '8', '9', '+', '/'};

    static {
//        try {
//            Resource resource = new ClassPathResource("/kuaidi.properties");//
//            props = PropertiesLoaderUtils.loadProperties(resource);
            mapCompany = new HashMap<String, String>();
            mapCompany.put("shentong", "STO");
            mapCompany.put("shunfeng", "SF");
            mapCompany.put("yuantong", "YTO");
            mapCompany.put("yunda", "YD");
            mapCompany.put("zhongtong", "ZTO");
            mapCompany.put("ems", "EMS");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * deliverystatus	物流状态 1在途中 2派件中 3已签收 4派送失败(拒签等)
     *
     * @param company 物流公司编码
     * @param number  物流单号
     * @return json
     */
    public static String getLogisticsInformation(String company, String number) {
        try {
            List<String> js_used_company = null;
            if (S.isNotBlank(js_company)) {
                js_used_company = Arrays.asList(js_company.split(","));
            }
            if (js_used_company != null && js_used_company.contains(company)) {//快递100
                String info = KuaiDiUtils.getKuaiDi100(company, number);
                JSONObject objs = (JSONObject) JSON.parse(info);
                Map<String, Object> map = new HashMap<String, Object>();
                Map<String, Object> resultmap = new HashMap<String, Object>();
                for (Map.Entry<String, Object> entry : objs.entrySet()) {
                    if ("com".equals(entry.getKey())) {
                        resultmap.put("type", entry.getValue());
                    } else if ("nu".equals(entry.getKey())) {
                        resultmap.put("number", entry.getValue());
                    } else if ("message".equals(entry.getKey())) {
                        map.put("msg", entry.getValue());
                    } else if ("state".equals(entry.getKey())) {
                        //快递100state：0：在途      1：揽件  2：疑难 3：签收  4：退签  5：派件   6：退回
                        // 对应关系       1           2         4       3          4       2     4
                        if ("0".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "1");
                        } else if ("1".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "2");
                        } else if ("2".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "4");
                        } else if ("3".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "3");
                        } else if ("4".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "4");
                        } else if ("5".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "2");
                        } else if ("6".equals(entry.getValue())) {
                            resultmap.put("deliverystatus", "4");
                        }

                    } else if ("status".equals(entry.getKey())) {
                        if ("200".equals(entry.getValue())) {//状态码变成0为成功和极速一致
                            map.put("status", "0");
                        } else {
                            map.put("status", "1");
                        }
                    } else if ("data".equals(entry.getKey())) {
                        //data处理begin:context替换成status
                        JSONArray datas = (JSONArray) JSON.parseArray(entry.getValue().toString());
                        List<Map<String, Object>> new_list = new ArrayList<Map<String, Object>>();
                        for (Object data : datas) {
                            Map<String, Object> mapDatas = new HashMap<String, Object>();
                            for (Map.Entry<String, Object> d : ((Map<String, Object>) data).entrySet()) {
                                if ("context".equals(d.getKey())) {
                                    mapDatas.put("status", d.getValue());
                                } else if ("time".equals(d.getKey())) {
                                    mapDatas.put(d.getKey(), d.getValue());
                                }
                            }
                            new_list.add(mapDatas);
                        }
                        //data处理end-----------------------------------------
                        resultmap.put("list", new_list);
                    }
                    map.put("result", resultmap);
                }
                return JSON.toJSONString(map, false);
            } else {//快递鸟
                String info = KuaiDiUtils.getKdiNiao(company, number);
                JSONObject objs = (JSONObject) JSON.parse(info);
                Map<String, Object> map = new HashMap<String, Object>();
                Map<String, Object> resultmap = new HashMap<String, Object>();
                for (Map.Entry<String, Object> entry : objs.entrySet()) {
                    if ("Success".equals(entry.getKey())) {
                        if ((Boolean) entry.getValue()) {
                            map.put("msg", "ok");
                            map.put("status", "0");
                        } else {
                            map.put("msg", objs.get("Reason"));
                            map.put("status", "1");
                        }
                    } else if ("LogisticCode".equals(entry.getKey())) {
                        resultmap.put("number", entry.getValue());
                    } else if ("ShipperCode".equals(entry.getKey())) {
                        resultmap.put("type", entry.getValue());
                    } else if ("State".equals(entry.getKey())) {
                        resultmap.put("deliverystatus", entry.getValue());
                    } else if ("Traces".equals(entry.getKey())) {
                        //data处理begin:context替换成status
                        JSONArray datas = (JSONArray) JSON.parseArray(entry.getValue().toString());
                        List<Map<String, Object>> new_list = new ArrayList<Map<String, Object>>();
                        for (Object data : datas) {
                            Map<String, Object> mapDatas = new HashMap<String, Object>();
                            for (Map.Entry<String, Object> d : ((Map<String, Object>) data).entrySet()) {
                                if ("AcceptStation".equals(d.getKey())) {
                                    mapDatas.put("status", d.getValue());
                                } else if ("AcceptTime".equals(d.getKey())) {
                                    mapDatas.put("time", d.getValue());
                                }
                            }
                            new_list.add(mapDatas);
                        }
//                        CollectionUtils.sort(new_list, true);
                        new_list.sort(Comparator.comparing(o -> ((String) o.get("time"))));
                        //data处理end-----------------------------------------
                        resultmap.put("list", new_list);
                    }

                    map.put("result", resultmap);
                }
                return JSON.toJSONString(map, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject json = new JSONObject();
            json.put("msg", "抱歉，暂时没有该单号的物流信息");
            json.put("result", new JSONObject());
            json.put("status", "205");
            return json.toJSONString();
        }


    }



    //快递100
    private static String getKuaiDi100(String company, String number) {
        String api_url = kd_url+ "?id=" + kd_key + "&com=" + company + "&nu=" + number + "&show=0&muti=1&order=desc";
        return HttpUtils.doGet(api_url);
    }

    public static String getNewKuaiDi100(String company, String number) {
        String param ="{\"com\":\""+company+"\",\"num\":\""+number+"\"}";
        String customer ="FDA550DFB5D676B51239CF1F58F403C6A";
        String key = "qUvSQHug940";
        String sign=null;
        try {
            sign= KuaiDiMD5.encode(param+key+customer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        HashMap params = new HashMap();
        params.put("param",param);
        params.put("sign",sign);
        params.put("customer",customer);
        return HttpUtils.doPost("http://poll.kuaidi100.com/poll/query.do",params, "utf-8").toString();
    }



    public static void main(String[] args) {
//        String test = ;
//        System.out.println(getLogisticsInformation("wanxiangwuliu", "032479710474762-1"));
//        String test1 = getLogisticsInformation("shunfeng", "304580240545");
//        System.out.println(test1);
//        System.out.println(getLogisticsInformation("shentong", "400049792945"));
          System.out.println(getNewKuaiDi100("zhongtong", "215352763228"));

    }



    /**
     * "kuaidi": {
     * "msg": "请求超过次数限制",
     * "result": "",
     * "status": "104"
     * 101	APPKEY为空或不存在
     * 102	APPKEY已过期
     * 103	APPKEY无请求此数据权限
     * 104	请求超过次数限制
     * 105	IP被禁止
     * 106	IP请求超过限制
     * 107	接口维护中
     * 108
     * <p>
     * 状态为104时,特殊处理result
     * }
     */
    private static String getJiSu(String company, String number) {
        String api_url = js_url + "?appkey=" + js_key + "&type=auto&number=" + number;
        String kuaidi = HttpUtils.doGet(api_url);
        JSONObject json = JSON.parseObject(kuaidi);
        if (json == null) {
            json = new JSONObject();
            json.put("result", new JSONObject());
            return json.toJSONString();
        }
        if (!json.getString("status").equals("0")) {
            json.put("result", new JSONObject());
        }
        return json.toJSONString();
    }

    //快递鸟快递
    private static String getKdiNiao(String company, String number) {
        try {
            String requestData = "{'OrderCode':'','ShipperCode':'" + mapCompany.get(company) + "','LogisticCode':'" + number + "'}";
            Map<String, String> params = new HashMap<String, String>();
            params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
            params.put("EBusinessID", kdn_id);
            params.put("RequestType", "1002");
            String dataSign = encrypt(requestData, kdn_key, "UTF-8");

            params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
            params.put("DataType", "2");
            return sendPost(kdn_url, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 电商Sign签名生成
     *
     * @param content  内容
     * @param keyValue Appkey
     * @param charset  编码方式
     * @return DataSign签名
     * @throws UnsupportedEncodingException ,Exception
     */
    private static String encrypt(String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception {
        if (keyValue != null) {
            return base64(MD5(content + keyValue, charset), charset);
        }
        return base64(MD5(content, charset), charset);
    }

    /**
     * base64编码
     *
     * @param str     内容
     * @param charset 编码方式
     * @throws UnsupportedEncodingException
     */
    private static String base64(String str, String charset) throws UnsupportedEncodingException {
        String encoded = base64Encode(str.getBytes(charset));
        return encoded;
    }

    private static String MD5(String str, String charset) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes(charset));
        byte[] result = md.digest();
        StringBuffer sb = new StringBuffer(32);
        for (int i = 0; i < result.length; i++) {
            int val = result[i] & 0xff;
            if (val <= 0xf) {
                sb.append("0");
            }
            sb.append(Integer.toHexString(val));
        }
        return sb.toString().toLowerCase();
    }

    public static String base64Encode(byte[] data) {
        StringBuffer sb = new StringBuffer();
        int len = data.length;
        int i = 0;
        int b1, b2, b3;
        while (i < len) {
            b1 = data[i++] & 0xff;
            if (i == len) {
                sb.append(base64EncodeChars[b1 >>> 2]);
                sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
                sb.append("==");
                break;
            }
            b2 = data[i++] & 0xff;
            if (i == len) {
                sb.append(base64EncodeChars[b1 >>> 2]);
                sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
                sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
                sb.append("=");
                break;
            }
            b3 = data[i++] & 0xff;
            sb.append(base64EncodeChars[b1 >>> 2]);
            sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
            sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
            sb.append(base64EncodeChars[b3 & 0x3f]);
        }
        return sb.toString();
    }

    private static String sendPost(String url, Map<String, String> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // POST方法
            conn.setRequestMethod("POST");
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            // 发送请求参数
            if (params != null) {
                StringBuilder param = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if (param.length() > 0) {
                        param.append("&");
                    }
                    param.append(entry.getKey());
                    param.append("=");
                    param.append(entry.getValue());
                    //System.out.println(entry.getKey()+":"+entry.getValue());
                }
                //System.out.println("param:"+param.toString());
                out.write(param.toString());
            }
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }



}
